package com.DTC;

import java.util.ArrayList;
import java.util.Collections;

public class Divide {                       //工具类
    public Double mid = 0.0;
    public Double gain = 0.0;

    public Divide(ArrayList<IrisEntry> data,int attrNum){
        divide(data, attrNum);
    }

    private ArrayList<Double> getMidList(ArrayList<Double> attrList){      //获取属性list各个值的中值
        Collections.sort(attrList);
        ArrayList<Double> attrMidList = new ArrayList<>();
        for(int i=0; i<attrList.size()-1; i++){
            attrMidList.add((attrList.get(i)+attrList.get(i+1))/2);
        }
        return attrMidList;
    }

    private Double Ent_D(ArrayList<IrisEntry> data){       //求Ent(D)
        int setosaNum = 0;
        int versicolorNum = 0;
        int virginicaNum = 0;
        for (IrisEntry irisEntry : data) {
            switch(irisEntry.getFlowerType()){
                case setosa:{
                    setosaNum++;
                    break;
                }
                case versicolor:{
                    versicolorNum++;
                    break;
                }
                case virginica:{
                    virginicaNum++;
                    break;
                }
            }
        }
        double d1=0,d2=0,d3=0;
        if(setosaNum!=0){
            d1 = - (setosaNum / (data.size()+0.0)) * (Math.log(setosaNum / (data.size()+0.0)));
        }
        if(versicolorNum!=0){
            d2 = - (versicolorNum / (data.size()+0.0)) * (Math.log(versicolorNum / (data.size()+0.0)));
        }
        if(virginicaNum!=0){
            d3 = - (virginicaNum / (data.size()+0.0)) * (Math.log(virginicaNum / (data.size()+0.0)));
        }

        // System.out.println("setosaNum\t"+setosaNum);
        // System.out.println("(data.size()+0.0)\t"+(data.size()+0.0));
        // System.out.println("log\t"+(Math.log(setosaNum / (data.size()+0.0))/Math.log(2)));
        return d1+d2+d3;
    }
    private Double Gain_D_a(ArrayList<IrisEntry> data, int attrNum, Double mid){      //求Gan(D,a)

        ArrayList<IrisEntry> lowList = new ArrayList<>();
        ArrayList<IrisEntry> highList = new ArrayList<>();
        for (IrisEntry irisEntry : data) {
            if(irisEntry.getDataByArray()[attrNum]>mid){
                highList.add(irisEntry);
            }else{
                lowList.add(irisEntry);
            }
        }
        // System.out.println("low"+(low));
        // System.out.println("data.size"+((data.size()+0.0)));
        // System.out.println("ent_d"+(Ent_D(highList)));
        Double a = Ent_D(data)-(((lowList.size()/(data.size()+0.0))*Ent_D(lowList))+(highList.size()/(data.size()+0.0))*Ent_D(highList));
        return a;
    }

    public void divide(ArrayList<IrisEntry> data,int attrNum){       //对第attrNum计算最大信息增益的值
        ArrayList<Double> attrList = new ArrayList<Double>();
        for (IrisEntry d : data) {                   
            attrList.add(d.getDataByArray()[attrNum]);
        }
        ArrayList<Double> attrMidList = getMidList(attrList);
        Double tmp=0.0;
        Double tmpGain=0.0;
        for (Double mid : attrMidList) {
            Double gain = Gain_D_a(data, attrNum, mid);
            if(tmpGain < gain){
                tmp = mid;
                tmpGain = gain;
            }
        }
        this.mid = tmp;
        this.gain = tmpGain;
    }

}
